from django.core.files.storage import Storage
from fdfs_client.client import Fdfs_client
from mall import settings
from django.utils.deconstruct import deconstructible

# 1.自定义存储系统必须是以下子类 django.core.files.storage.Storage


@deconstructible
class FastDFSStorage(Storage):
    # 2.Django必须能够在没有任何参数的情况下实例化您的存储系统。
    # 这意味着任何设置都应该来自django.conf.settings
    def __init__(self, path=None, ip=None):

        if path is None:
            path = settings.FDFS_CLIENT_CONF
        self.conf_path = path

        if ip is None:
            ip = settings.FDFS_URL
        self.ip = ip

    # 3.您的存储类必须实现_open()和_save() 方法以及适用于您的存储类的任何其他方法。
    # 采用了FastDFS打开图片,FastDFS是通过HTTP打开图片的可以省略这一步骤
    def _open(self, name, mode='rb'):
        pass

    # 保存
    # 需要自定义实现
    def _save(self, name, content, max_length=None):

        # name:只是一个文件名,并不是一个路径
        # content:是上传的内容,通过content.read()来获取文件的二进制内容

        # 1.创建FastDFS的客户端,加载配置文件
        # client = Fdfs_client('utils/fastdfs/client.conf')
        client = Fdfs_client(self.conf_path)
        # 2.上传文件
        # 获取文件的二进制内容
        file_data = content.read()
        # buffer上传二进制数据
        result = client.upload_by_buffer(file_data)
        # 3.判断上传的状态,如果上传成功,需要获取
        # 可以根据result中的Status来判断是否上传成功
        if result.get('Status') == 'Upload successed.':
            # 返回上传的字符串
            return result.get('Remote file_id')
        else:
            raise Exception('上传失败')

    # 判断文件是否存在
    def exists(self, name):
        # 判断文件是否存在，FastDFS可以自行解决文件的重名问题
        # 所以此处返回False，告诉Django上传的都是新文件
        return False

    # 获取图片路径
    def url(self, name):
        # 返回文件的完整URL路径
        # return "http://192.168.229.133:8888/" + name
        return self.ip + name

